/*
 * @Description:
 * @Version: @1.0.0
 * @Autor: YJY
 * @Date: 2021-07-20 16:05:40
 * @LastEditors: YJY
 * @LastEditTime: 2021-07-20 16:27:22
 */
import { foreachV } from './utils'

let Vue
export class Store { // 容器
  constructor (options) {
    console.log(options)
    // 实现 state 功能  而且响应式

    // 实现getters功能  并且具有缓存机制
    const computed = {}
    const getters = options.getters
    this.getters = {}
    foreachV(getters, (key, fn) => {
      computed[key] = () => {
        return fn(this.state)
      }
      Object.defineProperty(this.getters, key, {
        get: () => {
          return this.vm[key]
        }
      })
    })
    this.vm = new Vue({
      data: {
        state: options.state
      },
      computed
    })

    //
    const mutations = options.mutations
    this.mutations = {}
    foreachV(mutations, (key, fn) => {
      this.mutations[key] = (data) => {
        return fn(this.state, data)
      }
    })
    const actions = options.actions
    this.actions = {}
    foreachV(actions, (key, fn) => {
      this.actions[key] = (data) => {
        return fn(this, data)
      }
    })
  }

  // 实现 mutations
  commit = (name, data) => {
    this.mutations[name](data)
  }

  // 实现 异步
  dispatch = (name, data) => {
    this.actions[name](data)
  }

  // 添加属性监听  实现响应式
  get state () {
    return this.vm.state
  }
}

// 为每一个所用的实例添加一个$store
export const install = (_Vue) => { // 开发插件  引入Vue实例
  Vue = _Vue
  Vue.mixin({
    beforeCreate () { // 表明Vue的渲染关系 父子关系
      const options = this.$options
      if (options.store) { // 为根实例
        this.$store = options.store
      } else { // 再判断是否有父实例
        this.$store = this.$parent && this.$parent.$store
      }
    }
  })
}
